/*
 * @Description: User - service
 * @Author: Yong
 * @Date: 2021-09-29 21:27:42
 * @LastEditTime: 2021-10-09 23:41:11
 */
import { Context } from "@midwayjs/koa"
import { Provide, Inject } from "@midwayjs/decorator"
import { InjectEntityModel } from "@midwayjs/orm"
import { Repository, Not, Like } from "typeorm"
import { User } from "../entity/User.entity"
import { UserInfo } from "../interface"
import { bcryptHash, bcryptCompareSync, resHandler, verify } from "../utils"
import { Friends } from "../entity/Friends.entity"
@Provide()
export class UserService {
    @Inject()
    ctx: Context

    @InjectEntityModel(User)
    userModel: Repository<User>

    @InjectEntityModel(Friends)
    friendsModel: Repository<Friends>

    // 添加用户
    async addUser(userInfo: UserInfo) {
        const { U_LoginID } = userInfo
        // 判断用户是否注册
        const isExist = await this.getUserByLoginID(U_LoginID)
        if (isExist) {
            this.ctx.body = resHandler.errorRes({
                msg: "当前用户已注册",
                code: 200,
            })
        } else {
            await this.saveUser(userInfo)
            this.ctx.body = resHandler.successRes()
        }
    }

    // User表 - 增加用户
    async saveUser(userInfo: UserInfo) {
        const user = new User()
        // 加密密码
        userInfo.U_Password = bcryptHash(userInfo.U_Password)
        await this.userModel.save({ ...user, ...userInfo })
    }

    // User表 - 获取用户信息
    async getUserByLoginID(U_LoginID: string) {
        let userInfo = await this.userModel.findOne({
            where: { U_LoginID },
            select: ["ID", "U_LoginID", "U_nickName", "U_Avatar", "U_Password"],
        })
        if (!userInfo) return null
        return userInfo
    }

    // 登录
    async login(userInfo: UserInfo) {
        const { U_LoginID, U_Password } = userInfo
        if (!U_LoginID || !U_Password) {
            this.ctx.body = resHandler.errorRes({
                msg: "用户或者密码不能为空",
                code: 200,
            })
        } else {
            const user = await this.getUserByLoginID(U_LoginID)
            if (!user) {
                this.ctx.body = resHandler.errorRes({
                    msg: "未查询到当前用户",
                    code: 200,
                })
            } else {
                // 对比密码是否一致
                const isEqPwd = this.comparePassword(
                    U_Password,
                    user.U_Password
                )
                if (!isEqPwd) {
                    this.ctx.body = resHandler.errorRes({
                        msg: "用户或者密码不正确",
                        code: 200,
                    })
                } else {
                    delete user.U_Password
                    const token = verify.generateToken(user.ID)
                    this.ctx.body = resHandler.successRes({ ...user, token })
                }
            }
        }
    }

    // 对比密码是否正确
    comparePassword(pwd: string, comparePwd: string) {
        return bcryptCompareSync(pwd, comparePwd)
    }

    // 模糊匹配用户
    async searchUser (searchName: string, userID: string) {
        let userList = []
        console.log('searchName==>', searchName);
        console.log('userID==>', userID);
        // 搜索所有用户 - 不等于本身登录用户的其他用户
        if (!searchName) {
            userList = await this.userModel.find({
                where: { ID: Not(`${userID}`),  },
                select: ["ID", "U_LoginID", "U_nickName", "U_Avatar"],
            })
        } else {
            userList = await this.userModel.find({
                where: { ID: Not(`${userID}`), U_LoginID: Like(`%${searchName}%`) },   
                select: ["ID", "U_LoginID", "U_nickName", "U_Avatar"],
            })
        }
        // 循环查询出来的用户列表 - 判断是否是好友 - 添加state状态 0是好友状态 其他都是非好友状态
        const returnData = await Promise.all(userList.map(async item => {
            return { ...item, state: await this.isFriends(userID, item.ID) }
        }))

        this.ctx.body = resHandler.successRes(returnData)
    }

    /**
     * 查询好友表 - 判断是否是好友
     * @param uid 
     * @param fid 
     * @returns 
     */
    async isFriends (uid: string, fid: string) {
        const result = await this.friendsModel.findOne({
            where: { F_UserID: uid, F_FriendID: fid },
            select: ["F_FriendStatus"],
        })
        return result?.F_FriendStatus
    }
}
